//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "aura.h"
#include "wince.h"
#include "private.h"

AURA_API AuraSharedMemory_Create(
        /* [in] */ Aura_PWChar name,
        /* [in] */ Aura_MemorySize size,
        /* [in] */ Aura_Bool bCommit,
        /* [out] */ Aura_Handle * phSharedMemory,
        /* [out] */ Aura_Bool * pbAlreadyExisted)
{
    DWORD dwProtection = PAGE_READWRITE;
    HANDLE hSharedMemory = NULL;

    assert(NULL != name);
    assert(L'\0' != (wchar_t)name[0]);
    assert(NULL != phSharedMemory);
    assert(NULL != pbAlreadyExisted);

    DWORD dwMaxSizeLow = (size == 0 ? 0x01 : (DWORD)size);

    *pbAlreadyExisted = FALSE;
    hSharedMemory = CreateFileMappingW(INVALID_HANDLE_VALUE,
                                   NULL,
                                   dwProtection,
                                   0,
                                   dwMaxSizeLow,
                                  (LPCWSTR)(const wchar_t *)name);
    if (NULL == hSharedMemory) {
        goto E_FAIL_EXIT;
    }

    if (ERROR_ALREADY_EXISTS == GetLastError()) {
        *pbAlreadyExisted = TRUE;
    }

    *phSharedMemory = hSharedMemory;

    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

AURA_API AuraSharedMemory_Attach(
        /* [in] */ Aura_Handle hSharedMemory,
        /* [in] */ Aura_MemoryProtection protect,
        /* [out] */ Aura_Address * pAddress)
{
    LPVOID address = NULL;
    DWORD  dwAccess = 0;

    assert(NULL != hSharedMemory);
    assert(NULL != pAddress);

    dwAccess = ConvertToWinFileAccess(protect);
    address = MapViewOfFile(hSharedMemory, dwAccess, 0, 0, 0);
    if (NULL == address) {
        goto E_FAIL_EXIT;
    }
    *pAddress = (Aura_Address)address;

    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

AURA_API AuraSharedMemory_Detach(
        /* [in] */ Aura_Handle hSharedMemory,
        /* [in] */ Aura_Address address)
{
    BOOL bSuccess = FALSE;
    assert(NULL != hSharedMemory);

    bSuccess = UnmapViewOfFile((LPCVOID)address);
    if (!bSuccess) {
        goto E_FAIL_EXIT;
    }
    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

AURA_API AuraSharedMemory_Destroy(
        /* [in] */ Aura_Handle hSharedMemory)
{
    BOOL bSuccess = FALSE;

    assert(NULL != hSharedMemory);
    bSuccess = CloseHandle(hSharedMemory);
    if (!bSuccess) {
        goto E_FAIL_EXIT;
    }

    return AURA_NOERROR;

E_FAIL_EXIT:
    return GetLastAuraECode();
}

